var SVGDrawer = AbstractDrawer.extend({
    draw : function(shape){
        if(shape == null){
            this._drawAll();
        }else if(shape instanceof Point){
            this._drawPoint(shape);
        }else if(shape instanceof Line){
            this._drawLine(shape);
        }else if(shape instanceof Polygon || shape instanceof Polyline){
            this._drawPolyline(shape);
        }else if(shape instanceof HTMLContainer){
            this._drawHTMLContainer(shape);
        }else if(shape instanceof Rectangle){
            this._drawRectangle(shape);
        }else if(shape instanceof Circle){
            this._drawCircle(shape);
        }else if(shape instanceof Ellipse){
            this._drawEllipse(shape);
        }else if(shape instanceof Composite){
            this._drawComposite(shape);
        }

        if(shape && !shape.isPartOfComposite()){
            this.getWorkspace().appendChild(shape.element);
        }

        return shape;
    },
    _drawLine: function(line){
        line.element = this._createSVGElement("line",{
                "x1": line.getStart().getX(),
                "y1": line.getStart().getY(),
                "x2": line.getEnd().getX(),
                "y2": line.getEnd().getY()
            }
        );
        if(!line.isPartOfComposite()){
            this._setSVGAttributes(line.element, {
                "stroke-width": 1,
                "stroke": "black",
                "fill": "transparent"
            });
        }
        this._setSVGAttributes(line.element, line.options);
    },
    _drawPolyline: function(polyline){

        var pointsStringBuilder = new Array();
        for(var i = 0 ; i < polyline.getPoints().length ; i++){
            pointsStringBuilder.push(polyline.getPoints()[i].getX()+","+polyline.getPoints()[i].getY());
        }
        var pointsString = pointsStringBuilder.join(" ");

        polyline.element = this._createSVGElement(polyline instanceof Polygon ? "polygon" : "polyline",{
                "points": pointsString
            }
        );

        if(!polyline.isPartOfComposite()){
            this._setSVGAttributes(polyline.element, {
                "stroke-width": 1,
                "stroke": "black",
                "fill": "transparent"
            });
        }
        this._setSVGAttributes(polyline.element, polyline.options);
    },
    _drawPoint: function(point){
        point.element = this._createSVGElement("circle",{
                "cx": point.getX(),
                "cy": point.getY(),
                "r": 3
            }
        );
        this._setSVGAttributes(point.element, point.options);
    },
    _drawRectangle: function(rectangle){
        rectangle.element = this._createSVGElement("rect",{
                "x": rectangle.getOrigin().getX(),
                "y": rectangle.getOrigin().getY(),
                "width": rectangle.getWidth(),
                "height": rectangle.getHeight()
            }
        );

        if(!rectangle.isPartOfComposite()){
            this._setSVGAttributes(rectangle.element, {
                "stroke-width": 1,
                "stroke": "black",
                "fill": "transparent"
            });
        }
        this._setSVGAttributes(rectangle.element, rectangle.options);
    },
    _drawCircle: function(circle){
        circle.element = this._createSVGElement("circle",{
                "cx": circle.getOrigin().getX(),
                "cy": circle.getOrigin().getY(),
                "r": circle.getRadius()
            }
        );
        if(!circle.isPartOfComposite()){
            this._setSVGAttributes(circle.element, {
                "stroke-width": 1,
                "stroke": "black",
                "fill": "transparent"
            });
        }
        this._setSVGAttributes(circle.element, circle.options);
    },
    _drawEllipse: function(ellipse){
        ellipse.element = this._createSVGElement("ellipse",{
                "cx": ellipse.getOrigin().getX(),
                "cy": ellipse.getOrigin().getY(),
                "rx": ellipse.getXRadius(),
                "ry": ellipse.getYRadius()
            }
        );
        if(!ellipse.isPartOfComposite()){
            this._setSVGAttributes(ellipse.element, {
                "stroke-width": 1,
                "stroke": "black",
                "fill": "transparent"
            });
        }
        this._setSVGAttributes(ellipse.element, ellipse.options);
    },
    _drawComposite: function(composite){
        composite.element = this._createSVGElement("g");
        this._setSVGAttributes(composite.element, {
            "stroke-width": 1,
            "stroke": "black",
            "fill": "transparent"
        });
        this._setSVGAttributes(composite.element, composite.options);
        for(var i = 0 ; i < composite.getShapes().length ; i++){
            this.draw(composite.getShapes()[i], true);
            composite.element.appendChild(composite.getShapes()[i].element);
        }
    },
    _drawHTMLContainer: function(container){
        container.element = this._createSVGElement("foreignObject",{
                "x": container.getOrigin().getX(),
                "y": container.getOrigin().getY(),
                "width": container.getWidth(),
                "height": container.getHeight()
            }
        );
        container.element.appendChild(container.getHTMLNode());
        this._setSVGAttributes(container.element, container.options);
    },
    _drawAll: function(){
        for(var i = 0 ; i < this.getShapes().length ; i++){
            this.draw(this.getShapes()[i]);
        }
    },
    clearAll: function(){
        if ( this.getWorkspace().hasChildNodes() ){
            while ( this.getWorkspace().childNodes.length >= 1 ){
                this.getWorkspace().removeChild( this.getWorkspace().firstChild );
            }
        }
    },
    clear: function(shape){
        if(shape.element){
            this.getWorkspace().removeChild(shape.element);
        }
    },
    _createSVGElement:function(type, attributes){
        var element = document.createElementNS("http://www.w3.org/2000/svg" , type);
        this._setSVGAttributes(element, attributes);
        return element;
    },
    _setSVGAttributes:function (element, attributes){
        for(var attribute in attributes){
            var value = attributes[attribute];
            element.setAttributeNS(null, attribute, value);
        }
    },
    redraw: function(){
        this.clearAll();
        this.draw();
    }
});
